package org.etherframework.tests.features.mediator
{
	import org.etherframework.common.IContractual;
	import org.etherframework.core.IModule;
	import org.etherframework.mediator.IMediator;
	import org.etherframework.mediator.IMediators;
	import org.etherframework.tests.features.mediator.mediators.AutomaticallyCreatedViewMediator;
	import org.etherframework.tests.features.mediator.mediators.ManuallyCreatedViewMediator;
	import org.etherframework.tests.features.mediator.views.AutomaticallyCreatedView;
	import org.etherframework.tests.features.mediator.views.ManuallyCreatedView;
	import org.etherframework.tests.utils.ModuleInfo;
	import org.etherframework.tests.utils.TestUtility;
	import org.fluint.uiImpersonation.UIImpersonator;
	import org.hamcrest.assertThat;
	import org.hamcrest.object.equalTo;
	import org.hamcrest.object.notNullValue;
	import org.hamcrest.object.nullValue;
	
	import spark.components.Group;

	public class when_creating_mediators
	{	
		private static var _testUtility:TestUtility = new TestUtility();
		private static var _module:IModule;
		private static var _m:IMediators;
		private static var _manuallyCreatedView:ManuallyCreatedView;
		private static var _manuallyCreatedViewMediator:ManuallyCreatedViewMediator;
		private static var _moduleView:Group;
		private static var _automaticallyCreatedView:AutomaticallyCreatedView;
		private static var _automaticallyCreatedViewMediator:AutomaticallyCreatedViewMediator;
		private static var _info:ModuleInfo;
		
		[BeforeClass]
		public static function setUpBeforeClass():void
		{
			_moduleView = UIImpersonator.addChild(new Group()) as Group;
			_info = _testUtility.createModuleInfo(null, _moduleView);
			_module = _info.module;
			_m = _module.mediators;
			
			_m.addMediator(ManuallyCreatedView, ManuallyCreatedViewMediator, IContractual);
			_m.addMediator(AutomaticallyCreatedView, AutomaticallyCreatedViewMediator, IContractual);
			
			_manuallyCreatedView = new ManuallyCreatedView();
			_manuallyCreatedViewMediator = _m.createMediator(_manuallyCreatedView) as ManuallyCreatedViewMediator;
			
			_automaticallyCreatedView = new AutomaticallyCreatedView();
			_moduleView.addElement(_automaticallyCreatedView);
			
			_automaticallyCreatedViewMediator = 
				_m.hasMediator(_automaticallyCreatedView) as AutomaticallyCreatedViewMediator;
		}
		
		[AfterClass]
		public static function tearDownAfterClass():void
		{
			_testUtility.dispose();
			UIImpersonator.removeAllChildren();
		}
		
		[Test(order=1)]
		public function it_should_be_created():void
		{
			assertThat(_manuallyCreatedViewMediator, notNullValue());
			assertThat(_manuallyCreatedViewMediator.mediatorView, equalTo(_manuallyCreatedView));
			
			assertThat(_automaticallyCreatedViewMediator, notNullValue());
			assertThat(_automaticallyCreatedViewMediator.mediatorView, equalTo(_automaticallyCreatedView));
		}
		
		[Test(order=2)]
		public function views_should_have_proper_contracts_assigned():void
		{
			var mediator:IMediator = _m.hasMediator(_manuallyCreatedView);
			
			// _manuallyCreatedView should not have contract as it was not added to stage.
			assertThat(_manuallyCreatedView.contract, nullValue());
			assertThat(_automaticallyCreatedView.contract, equalTo(_automaticallyCreatedViewMediator));
		}
		
		[Test(order=3)]
		public function it_should_throw_an_error_when_arguments_are_not_valid():void
		{
			var err:Error;
			
			try {
				_m.createMediator(null);
			} catch (e:*) {err = e;}
			assertThat(err, notNullValue());
			err = null;
			
			try {
				_m.createMediator(new Group());
			} catch (e:*) {err = e;}
			assertThat(err, notNullValue());
			err = null;
		}
		
		[Test(order=4)]
		public function it_should_throw_an_error_when_mediator_is_already_created():void
		{
			var err:Error;
			
			try {
				_m.createMediator(_automaticallyCreatedView);
			} catch (e:*) {err = e;}
			assertThat(err, notNullValue());
			err = null;
		}
		
		[Test(order=5)]
		public function correct_mediator_persistence_should_be_applied():void
		{
			// View _manuallyCreatedView was not added to stage so 
			// mediator should not be kept by the framework.
			assertThat(_info.controllers.hasController(_manuallyCreatedViewMediator), nullValue());
			// As framework keeps weak reference to a view for which we created mediator, so it should be there.
			assertThat(_m.hasMediator(_manuallyCreatedView), equalTo(_manuallyCreatedViewMediator));
			// View _automaticallyCreatedView was added to 
			// stage thus should be kept by the framework.
			assertThat(_m.hasMediator(_automaticallyCreatedView), notNullValue());
			assertThat(_info.controllers.hasController(_automaticallyCreatedViewMediator), notNullValue());
		}
		
	}
}